﻿#       powershell -ExecutionPolicy Bypass -File replace_text.ps1

# 设置UTF-8编码
$OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# 获取当前目录路径
$projectPath = Get-Location

# 获取脚本自身的完整路径
$scriptPath = $MyInvocation.MyCommand.Path

# 定义替换规则
$replacements = @(
    @{ Original = "com\.ruoyi"; Replacement = "com.hello" },
    @{ Original = "ruoyi-"; Replacement = "hello-" },
    @{ Original = "RuoYi"; Replacement = "Hello" },
    @{ Original = "ruoyi"; Replacement = "hello" },
    @{ Original = "\bRy\b"; Replacement = "Hi" },
    @{ Original = "\bry\b"; Replacement = "hi" },
    @{ Original = "若依"; Replacement = "Hi" }
)

# 创建不带BOM的UTF-8编码
$utf8NoBom = New-Object System.Text.UTF8Encoding $false

# 二进制文件扩展名列表，这些文件将被跳过
$binaryExtensions = @(".dll", ".exe", ".jar", ".war", ".ear", ".zip", ".tar", ".gz", ".rar", ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".ico", ".class")

# 定义替换函数
function Replace-Content {
    param (
        [string]$filePath
    )
    
    # 如果是脚本自身，则跳过处理
    if ($filePath -eq $scriptPath) {
        Write-Output "跳过脚本自身: $filePath"
        return
    }
    
    # 获取文件扩展名
    $extension = [System.IO.Path]::GetExtension($filePath)
    
    # 如果是二进制文件则跳过
    if ($binaryExtensions -contains $extension) {
        Write-Output "跳过二进制文件: $filePath"
        return
    }
    
    try {
        # 读取文件内容
        $content = [System.IO.File]::ReadAllText($filePath, [System.Text.Encoding]::UTF8)
        $originalContent = $content
        
        # 对于XML文件，使用更安全的替换方式
        if ($extension -eq ".xml" -or (Get-Content -Path $filePath -TotalCount 1) -match "^<\?xml") {
            Write-Output "处理XML文件: $filePath"
            
            # 创建一个唯一的标识符来替换XML标签，确保它不会与正常内容冲突
            $guid = [Guid]::NewGuid().ToString()
            $openTagMarker = "OPEN_XML_TAG_$guid"
            $closeTagMarker = "CLOSE_XML_TAG_$guid"
            
            # 存储所有的标签
            $tagStore = @()
            
            # 替换开始标签 < 为标记
            $content = $content -replace '<', $openTagMarker
            # 替换关闭标签 > 为标记
            $content = $content -replace '>', $closeTagMarker
            
            # 应用替换规则到非标签文本
            foreach ($rule in $replacements) {
                $content = [regex]::Replace($content, $rule.Original, $rule.Replacement, [System.Text.RegularExpressions.RegexOptions]::None)
            }
            
            # 恢复XML标签
            $content = $content -replace $openTagMarker, '<'
            $content = $content -replace $closeTagMarker, '>'
        }
        else {
            # 对于非XML文件，正常应用替换规则
            foreach ($rule in $replacements) {
                $content = [regex]::Replace($content, $rule.Original, $rule.Replacement, [System.Text.RegularExpressions.RegexOptions]::None)
            }
        }
        
        # 如果内容有变化，则写回文件 - 使用不带BOM的UTF-8
        if ($content -ne $originalContent) {
            [System.IO.File]::WriteAllText($filePath, $content, $utf8NoBom)
            Write-Output "更新文件内容: $filePath"
        }
    }
    catch {
        Write-Output "处理文件 $filePath 时出错: $_"
    }
}

# 定义重命名函数
function Rename-FileWithPattern {
    param (
        [string]$directory
    )
    
    # 获取所有文件和目录
    $items = Get-ChildItem -Path $directory -Recurse -Force
    
    # 先处理文件
    foreach ($file in $items | Where-Object { !$_.PSIsContainer }) {
        $oldFilePath = $file.FullName
        
        # 如果是脚本自身，则跳过处理
        if ($oldFilePath -eq $scriptPath) {
            Write-Output "跳过脚本自身重命名: $oldFilePath"
            continue
        }
        
        $fileName = $file.Name
        $newFileName = $fileName
        
        # 应用所有替换规则到文件名 - 使用区分大小写的替换
        foreach ($rule in $replacements) {
            # 使用[regex]::Replace方法并设置RegexOptions.None来进行区分大小写的替换
            $newFileName = [regex]::Replace($newFileName, $rule.Original, $rule.Replacement, [System.Text.RegularExpressions.RegexOptions]::None)
        }
        
        # 如果文件名发生变化，则重命名
        if ($newFileName -ne $fileName) {
            $newFilePath = Join-Path -Path $file.DirectoryName -ChildPath $newFileName
            try {
                Rename-Item -Path $oldFilePath -NewName $newFileName -Force
                Write-Output "重命名文件: $oldFilePath -> $newFilePath"
            }
            catch {
                Write-Output "重命名文件 $oldFilePath 失败: $_"
            }
        }
    }
    
    # 然后从底层目录开始处理目录，以避免路径问题
    foreach ($dir in ($items | Where-Object { $_.PSIsContainer } | Sort-Object -Property FullName -Descending)) {
        $oldDirPath = $dir.FullName
        $dirName = $dir.Name
        $newDirName = $dirName
        
        # 应用所有替换规则到目录名 - 使用区分大小写的替换
        foreach ($rule in $replacements) {
            # 使用[regex]::Replace方法并设置RegexOptions.None来进行区分大小写的替换
            $newDirName = [regex]::Replace($newDirName, $rule.Original, $rule.Replacement, [System.Text.RegularExpressions.RegexOptions]::None)
        }
        
        # 如果目录名发生变化，则重命名
        if ($newDirName -ne $dirName) {
            $newDirPath = Join-Path -Path (Split-Path -Path $oldDirPath -Parent) -ChildPath $newDirName
            try {
                Rename-Item -Path $oldDirPath -NewName $newDirName -Force
                Write-Output "重命名目录: $oldDirPath -> $newDirPath"
            }
            catch {
                Write-Output "重命名目录 $oldDirPath 失败: $_"
            }
        }
    }
}

# 主要执行逻辑
Write-Output "开始替换过程..."
Write-Output "项目路径: $projectPath"
Write-Output "脚本路径: $scriptPath"

# 获取所有文件
$allFiles = Get-ChildItem -Path $projectPath -Recurse -File -Force | Where-Object { $_.FullName -notlike "*\.git\*" }

# 替换文件内容
Write-Output "步骤1: 替换文件内容..."
foreach ($file in $allFiles) {
    Replace-Content -filePath $file.FullName
}

# 重命名文件和目录
Write-Output "步骤2: 重命名文件和目录..."
Rename-FileWithPattern -directory $projectPath

Write-Output "替换过程完成！"
Write-Output "注意：如果您使用Java或其他强类型语言，可能需要更新相关的import语句和引用。" 